<?php
	
	namespace Aspic\Form\Element;
	
	use Aspic\Security\Security as S;
	use Aspic as A;

	/**
	* Form elements ancestor, all form elements extends it
	*/
	abstract class AbstractElement {
		use A\Preset\OptionTrait {
			__construct as optionTraitInit;
		}
		
		/**
		 * Define if the element can be added to a form using add*className* method
		 * Some element that required for example variable reference in their constructor 
		 * may cause problem with passing arguments and then does not accept this.
		 */
		const ALLOW_DYNAMIC_ADD = true;
		
		protected $showAsLine; // Will the element be showned as a normal element in the form (with lineStart, end, ..)
		
		/**
		 *
		 * @var \Aspic\Form\Form Parent form containing this element
		 */
		private $parentForm;
		
		public function __construct(array $options = array()) {
			$this->optionTraitInit($options);
			
			$this->setShowAsLine(true);
			$this->setParentForm(null);
		}
		
		abstract public function out();
		
		/**
		* If the element need javascript to work, this function return the javascript code
		* Prefix your functions names with the name of the element to avoid same names
		*/
		public function outJs() {
			return '';
		}
		
		protected function setShowAsLine($showAsLine) {
			$this->showAsLine = (bool)$showAsLine;
		}
		
		public function isShownedAsLine() {
			return $this->showAsLine;
		}
		
		/**
		* Return the form array (containing form data) from data array given or defaultly get from request method
		*/
		public static function getFormArray($formData = null) {
			if($formData == null) {
				if($_SERVER['REQUEST_METHOD'] == 'GET') {
					$arr = $_GET;
				}
				else {
					$arr = $_POST;
				}
			}
			else {
				$arr = A\UArray::toArray($formData);
			}
			
			return $arr;
		}
		
		/**
		 * Return a default decorator object for given Form element
		 * @param self $el
		 * @todo implement it
		 */
		public static function getDefaultDecorator(self $el) {
			if ($el instanceof A\View\Form\Form) {
				/* @var $el A\View\Form\Form */
				if (A\View\Form\Form::isContainerElement($el)) {
					return new A\View\Form\Decorator\Form\Basic;
				}
				else {
					
				}
			}
			else {
				
			}
		}
		
	}
	
?>